package com.webauto.po;

import java.util.Map;

import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Strings;
import com.webauto.data_driver.YamlUtil;
import com.webauto.log.Log;
import com.webauto.pojo.Element;
import com.webauto.selenium.FindElementUtil;
import com.webauto.selenium.ManagerUtil;
import com.webauto.selenium.SeleniumDriverUtil;
import com.webauto.selenium.SwitchUtil;
import com.webauto.selenium.UseElementUtil;
import com.webauto.test_case.BaseCase;

/**
 * PS:po操作类
 * 
 * @author lkk
 *
 */
public class PO {
	// 页面元素集
	public Map<String, Map> page;
	// 页面数据集
	public Map<String, String> Datas;

	/**
	 * PS:初始化页面元素及页面测试数据
	 * 
	 * @param pageName 页面名称
	 * @param testData 测试数据
	 */
	public PO(String pageName, String testData) {
		// 获取指定页面的页面元素字典
		this.page = YamlUtil.pages.get(pageName);
		// 将测试数据转为map集合
		this.Datas = (Map<String, String>) JSON.parse(testData);
	}

	/**
	 * PS:初始化页面元素
	 * 
	 * @param pageName 页面名称
	 */
	public PO(String pageName) {
		// 获取指定页面的页面元素字典
		this.page = YamlUtil.pages.get(pageName);
	}

	/**
	 * PS:指定控件名进行点击
	 * 
	 * @param controlName 控件名
	 */
	public void click(String controlName) {
		try {
			//根据控件名获取元素定位实体类
			//Element element = getElementByControlName(controlName);
			//根据定位数据获取定位对象
			//By by = getByByValue(element.getBy(), element.getValue());
			//使用返回可点击元素方法获取元素再点击
			//FindElementUtil.waitFindElement(by).click();
			getWebElementByControlName(controlName).click();
		} catch (Exception e) {
			Log.error("+++" + controlName + "点击失败+++");
		}
	}

	/**
	 * PS:指定控件名进行输入
	 * 
	 * @param controlName 控件名
	 * @param dataKey     输入数据
	 */
	public void sendKeys(String controlName, String dataKey) {
		String data = Datas.get(dataKey);
		if(Strings.isNullOrEmpty(data)) {
			return;
		}
		try {
			getWebElementByControlName(controlName).sendKeys(data);
		} catch (Exception e) {
			Log.error("+++" + controlName + "输入内容失败+++");
		}
	}

	/**
	 * PS:获取指定控件的文本值
	 * 
	 * @param controlName 控件名
	 * @return 文本值
	 */
	public String getText(String controlName) {
		String text = "";
		try {
			text = getWebElementByControlName(controlName).getText();
		} catch (Exception e) {
			Log.error("+++" + controlName + "获取文本失败+++");
		}
		return text;
	}
	
	/**
	 * PS:富文本输入
	 * @param controlName 富文本输入框控件名
	 * @param text 输入文本
	 */
	public void richTextSendKeys(String controlName,String textKey) {
		String textvalue = Datas.get(textKey);
		//获取到指定控件的元素集实体类
		Element element = getElementByControlName(controlName);
		//获取控件的位置对象
		By by = getByByValue(element.getBy(), element.getValue());
		//使用键盘输入文字
		UseElementUtil.keyboardSendKeys(by, textvalue);
	}
	
	/**
	 * PS:判断页面加载是否完成
	 * 
	 * @param controlName 页面加载完成才取到的控件名
	 * @return 页面是否加载完成
	 */
	public boolean pageIfLoad(String controlName) {
		if (getWebElementByControlName(controlName) != null) {
			return true;
		}
		return false;
	}

	/**
	 * PS:切换到指定iframe
	 * 
	 * @param controlName iframe名称
	 */
	public void switchToFrame(String controlName) {
		WebElement element = getWebElementByControlName(controlName);
		SwitchUtil.switchToFrameByElement(element);
	}

	/**
	 * PS:根据控件名及选项名选择选项
	 * 
	 * @param controlName 控件名
	 * @param dataKey     选项名
	 */
	public void selectByVisibleText(String controlName, String optionName) {
		WebElement element = getWebElementByControlName(controlName);
		String option = Datas.get(optionName);
		Select select = new Select(element);
		try {
			ManagerUtil.sleep(1000);
			select.selectByVisibleText(option);
		} catch (Exception e) {
			Log.error("+++" + controlName + "选择失败+++");
		}

	}
	
	/**
	 * PS:根据检查点字符串获取检查元素的选择器对象
	 * @param checkPoint 检查点字符串
	 * @return 选择器对象
	 */
	public By getByByCheckPoint(String checkPoint) {
		String[] checkPoints = checkPoint.split(":");
		String by = checkPoints[0];
		String value = checkPoints[1];
		By result = getByByValue(by, value);
		return result;
	}
	
	/**
	 * PS:根据选择器类型以及地址获取元素
	 * 
	 * @param controlName 控制器名称
	 * @return 页面元素对象
	 */
	public WebElement getWebElementByControlName(String controlName) {
		// 根据控件获取Element对象
		Element element = getElementByControlName(controlName);
		// 从元素实体类获取by属性
		String by = element.getBy();
		// 从元素实体类获取value属性
		String value = element.getValue();
		// 最终返回页面元素对象
		WebElement webElement = null;
		// 通过by判断使用哪种控制器查找元素
		if ("id".equalsIgnoreCase(by)) {
			webElement = FindElementUtil.waitFindElementForPageLoad(By.id(value));
		} else if ("name".equalsIgnoreCase(by)) {
			webElement = FindElementUtil.waitFindElementForPageLoad(By.name(value));
		} else if ("className".equalsIgnoreCase(by)) {
			webElement = FindElementUtil.waitFindElementForPageLoad(By.className(value));
		} else if ("tagName".equalsIgnoreCase(by)) {
			webElement = FindElementUtil.waitFindElementForPageLoad(By.tagName(value));
		} else if ("linkText".equalsIgnoreCase(by)) {
			webElement = FindElementUtil.waitFindElementForPageLoad(By.linkText(value));
		} else if ("cssSelector".equalsIgnoreCase(by)) {
			webElement = FindElementUtil.waitFindElementForPageLoad(By.cssSelector(value));
		} else if ("xPath".equalsIgnoreCase(by)) {
			webElement = FindElementUtil.waitFindElementForPageLoad(By.xpath(value));
		} else {
			throw new AssertionError("+++暂不支持该选择器,选择器名称:" + by + "+++");
		}
		return webElement;
	}

	/**
	 * PS:根据控件名获取获取控件元素实体类
	 * 
	 * @param controlName
	 * @return
	 */
	public Element getElementByControlName(String controlName) {
		// 从页面获取控件map对象,通过fastJson转为json字符串
		String elementsJSON = JSON.toJSONString(this.page.get(controlName));
		// 将json字符串转为控件实体对象
		Element element = JSON.parseObject(elementsJSON, Element.class);
		return element;
	}
	
	/**
	 * PS:根据选择器类型及地址获取选择器对象
	 * @param by 选择器类型
	 * @param value 地址
	 * @return 选择器对象
	 */
	public By getByByValue(String by,String value) {
		By result = null;
		// 通过by判断使用哪种控制器查找元素
		if ("id".equalsIgnoreCase(by)) {
			result = By.id(value);
		} else if ("name".equalsIgnoreCase(by)) {
			result = By.name(value);
		} else if ("className".equalsIgnoreCase(by)) {
			result = By.className(value);
		} else if ("tagName".equalsIgnoreCase(by)) {
			result = By.tagName(value);
		} else if ("linkText".equalsIgnoreCase(by)) {
			result = By.linkText(value);
		} else if ("cssSelector".equalsIgnoreCase(by)) {
			result = By.cssSelector(value);
		} else if ("xPath".equalsIgnoreCase(by)) {
			result = By.xpath(value);
		} else {
			throw new AssertionError("+++暂不支持该选择器,选择器名称:" + by + "+++");
		}
		return result;
	}

}
